﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace FacebookTestUserManager
{
    /// <summary>
    /// CorrelationWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class CorrelationWindow : Window
    {
        public string AccessToken { set; get; }
        public string AppId { set; get; }

        public CorrelationWindow()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(CorrelationWindow_Loaded);

        }

        private Dictionary<TestUser, StackPanel> gridItemDictionary;
        private List<TestUser> userList;
        void CorrelationWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var helper = new FacebookHelper(this.AppId, this.AccessToken);
            var users = helper.GetTestUsers();

            var l = (int)decimal.Ceiling((decimal)Math.Sqrt(users.Count()));

            gridItemDictionary = new Dictionary<TestUser, StackPanel>();

            for (int i = 0; i < users.Count; i++)
            {
                var x = i % l;
                var y = i / l;

                var user = users[i];
                var uinfo = helper.Get(user.id, user.access_token);

                var sp = new StackPanel() {DataContext=user.login_url };
                sp.Width = 220;
                sp.Height = 100;
                sp.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                sp.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                sp.Margin = new Thickness(5);
                sp.SetValue(Canvas.LeftProperty, x * sp.Width);
                sp.SetValue(Canvas.TopProperty, y * sp.Height);
                
                sp.MouseLeftButtonDown += (s,e2) => {
                    FacebookHelper.NavigateTo((s as StackPanel).DataContext as string);
                };

                sp.Children.Add(new TextBlock() { Text = uinfo["id"] });
                sp.Children.Add(new TextBlock() { Text = uinfo["name"] });
                sp.Children.Add(new TextBlock() { Text = uinfo["gender"] });

                MainCanvas.Children.Add(sp);

                gridItemDictionary.Add(user, sp);
            }

            var connectedList = new List<Connection>();

            foreach (var user in users)
            {
                var sp = gridItemDictionary[user];

                dynamic friends = helper.Get("me/friends", user.access_token)["data"];

                if (friends.Count == 0)
                    continue;

                var userPoint = CenterPoint(GetCanvasTopLeft(sp), sp.Width, sp.Height);
                var brush = GetRandomBrush();


                foreach (var friend in friends)
                {
                    var id = friend["id"];

                    var friendUser = users.First(u => u.id == id);

                    if (connectedList.Count > 0)
                    {
                        bool skip = false;
                        foreach (var connection in connectedList)
                        {
                            if (connection.Connected(user, friendUser))
                            {
                                skip = true;
                                break;
                            }
                        }

                        if (skip) break;

                    }


                    var friendSp = gridItemDictionary[friendUser];

                    var friendPoint = CenterPoint(GetCanvasTopLeft(friendSp), friendSp.Width, friendSp.Height);

                    var line = new Line()
                    {
                        X1 = userPoint.X,
                        Y1 = userPoint.Y,
                        X2 = friendPoint.X,
                        Y2 = friendPoint.Y,
                        StrokeThickness = 1,
                        Stroke = brush,
                        Opacity= 0.8
                        
                    };

                    MainCanvas.Children.Add(line);
                    connectedList.Add(new Connection(user, friendUser));
                }



            }

        }

        private System.Windows.Media.Brush GetRandomBrush()
        {
            var random = new Random();

            SolidColorBrush brush = new SolidColorBrush();

            double r, g, b;

            double lightness = random.NextDouble() * 0.5 + 0.4; // not too dark nor too light

            double hue = random.NextDouble() * 360.0; // full hue spectrum

            double saturation = random.NextDouble() * 0.8 + 0.2; // not too grayish

            ColorTransform.HSLtoRGB(hue, saturation, lightness, out r, out g, out b);

            brush.Color = System.Windows.Media.Color.FromRgb((byte)(r * 255.0), (byte)(g * 255.0), (byte)(b * 255.0));

            return brush;

        }



        void MainGrid_Loaded(object sender, RoutedEventArgs e)
        {

            var helper = new FacebookHelper(this.AppId, this.AccessToken);

            foreach (var user in this.userList)
            {
                var sp = gridItemDictionary[user];

                dynamic friends = helper.Get("me/friends", user.access_token).data;

                if (friends.Count == 0)
                    continue;

                foreach (var friend in friends)
                {
                    var id = ((dynamic)friend).id.Value;

                    var friendUser = this.userList.First(u => u.id == id);
                    var friendSp = gridItemDictionary[friendUser];
                }



            }
        }

        Point GetCanvasTopLeft(FrameworkElement element)
        {
            var left = (double)element.GetValue(Canvas.LeftProperty);
            var top = (double)element.GetValue(Canvas.TopProperty);

            return new Point(left, top);
        }

        Point CenterPoint(Point topLeft, double width, double height)
        {
            return new Point(topLeft.X + width / 2, topLeft.Y + height / 2);
        }

        Point GetControlPosition(FrameworkElement myControl)
        {
            var windowTopLeft = this.PointToScreen(new Point(0, 0));

            Point locationToScreen = myControl.PointToScreen(windowTopLeft);
            PresentationSource source = PresentationSource.FromVisual(myControl);

            return source.CompositionTarget.TransformFromDevice.Transform(locationToScreen);
        }


    }

    public class Connection
    {
        public TestUser User1 { set; get; }
        public TestUser User2 { set; get; }
        public Connection(TestUser user1, TestUser user2)
        {
            this.User1 = user1;
            this.User2 = user2;
        }

        public bool Connected(TestUser user1, TestUser user2)
        {
            return this.User1.id == user1.id && this.User2.id == user2.id 
                || this.User1.id == user2.id && this.User2.id == user1.id;
        }
    }
}
